package com.swm.julie.rest.crud.twitt.search;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import com.swm.julie.rest.crud.twitt.TwittDocFormat;

public class SearchTwitt {

	String indexDir;
	
	public SearchTwitt()
	{
		
	}
	
	/**
	 * Search the twitts with the query.
	 * The query is analyzed with standard parser in Lucene applied at contents field.
	 * setIndexDir() must be called before this function. If not, return null with system err msg.
	 * return the result 500 twitts instance of ArrayList<TwittDocFormat>.
	 * @param query - query for searching terms in the contents field
	 * @return ArrayList of twitts
	 * @throws IOException
	 * @throws ParseException 
	 */
	public ArrayList<TwittDocFormat> search(String q) throws IOException, ParseException
	{
		if(indexDir == null || indexDir.length() == 0)
		{
			System.err.println("index search directory is null");
			return null;
		}

		Directory dir = FSDirectory.open(new File(indexDir));
		IndexSearcher is = new IndexSearcher(dir);
		
		ArrayList<TwittDocFormat> result = new ArrayList<TwittDocFormat>();

		QueryParser parser = new QueryParser(Version.LUCENE_33, "contents", new CJKAnalyzer(Version.LUCENE_33));
		Query query = parser.parse(q);
		
		TopDocs hits = is.search(query, 500);
		
		//Add twitts to the result set
		for(ScoreDoc scoreDoc : hits.scoreDocs)
		{
			TwittDocFormat twitt = new TwittDocFormat();
			Document doc = is.doc(scoreDoc.doc);

			twitt.setId(new Long(doc.get("id")));
			twitt.setContents(doc.get("contents"));
			twitt.setPostdate(doc.get("postdate"));
			twitt.setPostUrl(doc.get("url"));
			twitt.setLinkInfo(doc.get("linkInfo"));
			
			result.add(twitt);
		}
		
		is.close();

		System.out.println("SearchTwitt.search() : search " + result.size() + " twitts with '" + q +"' query.");
		return result;
	}

	/**
	 * Search twitts with the id.
	 * @param id - id of the twitt to search 
	 * @return
	 * @throws IOException 
	 */
	public TwittDocFormat search(long id) throws IOException
	{
		if(indexDir == null || indexDir.length() == 0)
		{
			System.err.println("index search directory is null");
			return null;
		}
		Directory dir = FSDirectory.open(new File(indexDir));
		IndexSearcher is = new IndexSearcher(dir);
		
		ArrayList<TwittDocFormat> result = new ArrayList<TwittDocFormat>();
		
		Query query = new TermQuery(new Term("id", String.valueOf(id)));
		
		TopDocs hits = is.search(query, 1);
		
		System.out.println("SearchTwitt.search() : search twitt with the id : " + id);
		
		if(hits.scoreDocs.length == 0)
		{
			is.close();
			dir.close();
			
			return null;
		}
		else
		{
			ScoreDoc scoreDoc = hits.scoreDocs[0];
			TwittDocFormat twitt = new TwittDocFormat();
			Document doc = is.doc(scoreDoc.doc);

			twitt.setId(new Long(doc.get("id")));
			twitt.setContents(doc.get("contents"));
			twitt.setPostdate(doc.get("postdate"));
			twitt.setPostUrl(doc.get("url"));
			twitt.setLinkInfo(doc.get("linkInfo"));
			
			is.close();
			dir.close();
		
			return twitt;
		}
	}
	
	/**
	 * Return the document of the searched Twitt.
	 * 
	 * @param id - id of index twitt
	 * @return Document - result of the search the twitt from the lucene
	 * @throws IOException
	 */
	public Document gethDocument(long id) throws IOException
	{
		if(indexDir == null || indexDir.length() == 0)
		{
			System.err.println("index search directory is null");
			return null;
		}
		Directory dir = FSDirectory.open(new File(indexDir));
		IndexSearcher is = new IndexSearcher(dir);
		
		ArrayList<TwittDocFormat> result = new ArrayList<TwittDocFormat>();
		
		Query query = new TermQuery(new Term("id", String.valueOf(id)));
		
		TopDocs hits = is.search(query, 1);
		
		System.out.println("SearchTwitt.search() return doc : search twitt with the id : " + id);
		
		if(hits.scoreDocs.length == 0)
		{
			is.close();
			dir.close();
			
			return null;
		}
		else
		{
			ScoreDoc scoreDoc = hits.scoreDocs[0];
			TwittDocFormat twitt = new TwittDocFormat();
			Document doc = is.doc(scoreDoc.doc);

			is.close();
			dir.close();
		
			return doc;
		}
	}
	
	/**
	 * set a index dir for search.
	 * It must be called before the search for set the dir.
	 * @param indexDir - index directory to search indexes
	 */
	public void setIndexDir(String indexDir) {
		this.indexDir = indexDir;
	}
}
